home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
dpmigcc5.zip
/
RSX
/
SOURCE
/
PTRACE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-12
|
4KB
|
164 lines
/*****************************************************************************
* FILE: ptrace.c *
* *
* DESC: *
* - ptrace handler *
* *
* Copyright (C) 1993,1994 *
* Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld *
* email: rainer@mathematik.uni-bielefeld.de *
* *
*****************************************************************************/
#include "DPMI.H"
#include "DPMI10.H"
#include "PROCESS.H"
#include "CDOSX32.H"
#include "START32.H"
#include "ADOSX32.H"
#include "COPY32.H"
#include "PTRACE.H"
#include "DOSERRNO.H"
#include "KDEB.H"
#define FLAG_MASK 0x00000dd9L
#define SINGLE_STEP 0x100
int do_ptrace(int request, int child_id, DWORD addr, DWORD data, DWORD * ret)
{
NEWPROCESS *child;
#ifdef CONFIG_KDEB
if (child_id == 1)
return KDEB_ptrace(request, addr, data, ret);
#endif
if (!(child = find_process(child_id)))
return EMX_ESRCH;
if (child->pptr != npz || !(child->p_flags & PF_DEBUG))
return EMX_ESRCH;
if (child->p_status != PS_STOP && child->p_status != PS_START)
return EMX_ESRCH;
*ret = 0;
switch (request) {
case PTRACE_TRACEME:
case PTRACE_SESSION:
return 0;
case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA:
if (verify_illegal(child, addr, 4))
return EMX_EIO;
*ret = read32(child->data32sel, addr);
return 0;
case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
if (verify_illegal(child, addr, 4))
return EMX_EIO;
if (dpmi10) {
WORD page, pageorg;
read32(child->data32sel, addr); /* page in */
if (GetPageAttributes(child->memhandle, addr & ~0xFFFL, 1, &pageorg))
return EMX_EIO;
pageorg &= ~16; /* don't modify access/dirty */
page = pageorg | 8; /* read/write access */
if (ModifyPageAttributes(child->memhandle, addr & ~0xFFFL, 1, &page))
return EMX_EIO;
store32(child->data32sel, addr, data);
ModifyPageAttributes(child->memhandle, addr & ~0xFFFL, 1, &pageorg);
} else
store32(child->data32sel, addr, data);
*ret = data;
return 0;
case PTRACE_EXIT:
/* to do : switch to child -> do_signal(); */
child->p_flags |= PF_WAIT_WAIT;
return 0;
case PTRACE_PEEKUSER:
if (addr == 0x30) { /* u_ar0 */
*ret = 0xE0000000 + ((DWORD) (UINT) & (child->regs));
return 0;
} else { /* peek regs */
DWORD *peekat;
peekat = (DWORD *) (UINT) (addr);
if (peekat < &(child->regs.gs) || peekat > &(child->regs.ss))
return EMX_EIO;
*ret = *peekat;
return 0;
}
case PTRACE_POKEUSER:
{
/* poke regs */
DWORD *pokeat;
pokeat = (DWORD *) (UINT) addr;
if (pokeat < &(child->regs.gs) || pokeat > &(child->regs.ss))
return EMX_EIO;
/* change data for critical regs */
if (pokeat == &(child->regs.eflags)) {
data &= FLAG_MASK;
data |= *pokeat & ~FLAG_MASK;
} else if (pokeat <= &(child->regs.ds)
|| pokeat == &(child->regs.cs))
data = *pokeat;
else if (pokeat == &(child->regs.esp)) {
if (verify_illegal(child, data, 4))
return EMX_EIO;
child->regs.esp = data;
child->regs.esporg = data + 12L;
} else if (pokeat == &(child->regs.esporg)) {
if (verify_illegal(child, data, 4))
return EMX_EIO;
child->regs.esporg = data;
child->regs.esp = data - 12L;
} else if (pokeat == &(child->regs.eip))
if (verify_illegal(child, data, 4))
return EMX_EIO;
*pokeat = data;
*ret = data;
return 0;
}
case PTRACE_STEP:
if ((int)data > 0 && (int)data <= MAX_SIGNALS)
send_signal(child, (WORD) data);
child->regs.eflags |= SINGLE_STEP;
if (child->regs.esp == child->regs.esporg)
child->regs.esp -= 12;
npz->p_status = PS_STOP;
switch_context(child);
npz->p_status = PS_RUN;
return 0;
case PTRACE_RESUME:
if ((int)data > 0 && (int)data <= MAX_SIGNALS)
send_signal(child, (int) data);
if (child->regs.esp == child->regs.esporg)
child->regs.esp -= 12;
npz->p_status = PS_STOP;
switch_context(child);
npz->p_status = PS_RUN;
return 0;
default:
return EMX_EIO;
}
}